#include "stdafx.h"
#include "PlayerMsgHandler.h"
#include "Message/MsgPlayer.h"
#include "Message/MsgCategory.h"
#include "Message/DBMessageRole.h"
#include "Message/DBMessageItem.h"
#include "Message/DBMessageForm.h"
#include "Message/DBMessageProgress.h"
#include "Entity/EntityBuilderWorld.h"
#include "Combat/CombatSysIf.h"
#include "Service/ServiceImpLgc.h"
#include "Entity/EntityDefinition.h"


PlayerMsgHandler::PlayerMsgHandler()
:m_wpEttMgrWorld(NULL), m_wpEttMgrLogin(NULL)
{
	
}

PlayerMsgHandler::~PlayerMsgHandler()
{

}

bool PlayerMsgHandler::initialize(IMsgHandlerInitData* data)
{
	MsgHandlerInitDataLgc* d = dynamic_cast<MsgHandlerInitDataLgc*>(data);
	if (d)
	{
		m_wpEttMgrLogin = d->wpEttMgrL;
		m_wpEttMgrWorld = d->wpEttMgrW;
		m_wpPlayerDataMgr = d->wpPlayerDataMgr;
		return __super::initialize(data);
	}
	else
		return false;
}


bool PlayerMsgHandler::handleMsg(IMsg* pMsg)
{
	//
	//	get current message owner: player entity
	m_wpCurEtt = m_wpEttMgrWorld->getEntity(pMsg->getSID());
	if (m_wpCurEtt)
	{
		m_wpCurPlayer = m_wpPlayerDataMgr->add(pMsg->getSID());
	}
	else
	{
		m_wpCurPlayer = NULL;
	}

	if (m_wpCurEtt==NULL)
	{
		pMsg->dump();
		LOG_ERROR("Failed to handle player message, null player for session: "<<pMsg->getSID());
		return false;
	}

	int nMsgCate = pMsg->getMsgCate();


	if(nMsgCate < Msg::MC_Cli_Max)
	{
		onRcvCliMsg(pMsg);
	}
	else if (nMsgCate==Msg::MC_DB_Role)
	{
		onRcvDBRoleMsg(pMsg);
	}
	else if (nMsgCate==Msg::MC_DB_Item)
	{
		onRcvDBItemMsg(pMsg);
	}
	else if (nMsgCate==Msg::MC_DB_Form)
	{
		onRcvDBFormMsg(pMsg);
	}
	else if (nMsgCate==Msg::MC_DB_Progress)
	{
		onRcvDBProgressMsg(pMsg);
	}
	
	
	return true;
}

void PlayerMsgHandler::onRcvCliMsg(IMsg* pMsg)
{
	switch(pMsg->getMsgID())
	{
	case MsgMainRoleInfoRequest::Id:
		onQueryMainRoleInfoRequest(pMsg);
		break;
	default:
		{
		}
	}
}

void PlayerMsgHandler::onRcvDBRoleMsg(IMsg* pMsg)
{
	switch(pMsg->getMsgID())
	{
	case MsgLoadMainRoleDetail::Id:
		onLoadMainRoleDetailResponse(pMsg);
		break;
	case MsgLoadRoles::Id:
		onLoadRolesResponse(pMsg);
		break;
	case MsgUpdateRole::Id:
		onUpdateRoleResponse(pMsg);
		break;
	case MsgRemoveRole::Id:
		onRemoveRoleResponse(pMsg);
		break;
	default:
		{
		}
	}
}

void PlayerMsgHandler::onRcvDBItemMsg(IMsg* pMsg)
{
	switch(pMsg->getMsgID())
	{
	case MsgLoadItems::Id:
		{
			break;
		}
	case MsgUpdateItem::Id:
		{
			break;
		}
	case MsgRemoveItem::Id:
		{
			break;
		}
	}
}

void PlayerMsgHandler::onRcvDBFormMsg(IMsg* pMsg)
{
	switch(pMsg->getMsgID())
	{
	case MsgLoadForms::Id:
		{
			MsgLoadForms* msg = dynamic_cast<MsgLoadForms*>(pMsg);
			if (msg)
			{
				Forms* fms= m_wpCurPlayer!=NULL? m_wpCurPlayer->getFormData() : NULL;
				if (fms!=NULL)
				{
					LOG_INFO("Forms data load twice for session: "<<pMsg->getSID());
				}
				else
				{
					fms = m_wpCurPlayer!=NULL? m_wpCurPlayer->setFormData() : NULL;

					for (MsgLoadForms::DBFormList::iterator it = msg->forms.begin();
						it!=msg->forms.end();
						it++)
					{
						DBForm& db = *it;
						if (db.ftype>=1 && db.ftype<=9)
						{
							fms->forms[db.ftype-1].set(db.flvl, db.fslot);
						}
						else
						{
							LOG_ERROR("Form data load, invalid form type : " <<(int)db.ftype);
						}
					}
				}
			}
			break;
		}
	case MsgUpdateForm::Id:
		{
			break;
		}
	}
}

void PlayerMsgHandler::onRcvDBProgressMsg(IMsg* pMsg)
{
	switch(pMsg->getMsgID())
	{
	case MsgLoadProgresss::Id:
		{
			MsgLoadProgresss* msg = dynamic_cast<MsgLoadProgresss*>(pMsg);
			if (msg)
			{
				Progress* pw= m_wpCurPlayer!=NULL? m_wpCurPlayer->getProgressData() : NULL;
				if (pw!=NULL)
				{
					LOG_INFO("Progress data load twice for session: "<<pMsg->getSID());
				}
				else
				{
					pw= m_wpCurPlayer!=NULL? m_wpCurPlayer->setProgressData() : NULL;

					for (MsgLoadProgresss::DBProgressList::iterator it = msg->progresss.begin();
						it!=msg->progresss.end();
						it++)
					{
						DBProgress& db = *it;
						ProgressDistrict* pd = pw->add(db.cid, db.did);
						pd->set(db.sid, db.data);
					}
				}
			}
			break;
		}
	}
}

void PlayerMsgHandler::onQueryMainRoleInfoRequest(IMsg* pMsg)
{
	if(!m_wpCurEtt)
	{
		LOG_ERROR("Entity is null in onQueryMainRoleInfoRequest");
		return;
	}

	if(!pMsg)
		return;

	//save the session ID first
	int sessionId = pMsg->getSID();

	MsgMainRoleInfoRequest* request = dynamic_cast<MsgMainRoleInfoRequest*>(pMsg);
	if(!request)
		return;

	MsgMainRoleInfoResponse* response = new MsgMainRoleInfoResponse;
	response->setSID(sessionId);
	response->errcode = ERR_FAILED;

	ICombatSys* pCombat = m_wpCurEtt->getCombatSys();
	if (pCombat)
	{
		response->vit = pCombat->getProps(prop_vit) + pCombat->getPropsModifier(prop_vit);
		response->str = pCombat->getProps(prop_str) + pCombat->getPropsModifier(prop_str);
		response->agi = pCombat->getProps(prop_agi) + pCombat->getPropsModifier(prop_agi);
		response->inte = pCombat->getProps(prop_int) + pCombat->getPropsModifier(prop_int);
		response->left = pCombat->getProps(prop_left) + pCombat->getPropsModifier(prop_left);

		response->hit = pCombat->getProps(prop_tohit) + pCombat->getPropsModifier(prop_tohit);
		response->dodge = pCombat->getProps(prop_tododge) + pCombat->getPropsModifier(prop_tododge);
		response->critical = pCombat->getProps(prop_critical) + pCombat->getPropsModifier(prop_critical);
		response->resist = pCombat->getProps(prop_resist) + pCombat->getPropsModifier(prop_resist);
		response->ap = pCombat->getProps(prop_ap) + pCombat->getPropsModifier(prop_ap);
		response->dp = pCombat->getProps(prop_dp) + pCombat->getPropsModifier(prop_dp);

		response->errcode = ERR_SUCCESS;
	}

	//	response to client
	getSvcHost()->postMsg(response);
}

void PlayerMsgHandler::onLoadMainRoleDetailResponse(IMsg* pMsg)
{
	if(!m_wpCurEtt)
	{
		LOG_ERROR("Entity is null in onLoadMainRoleDetailResponse");
		return;
	}

	MsgLoadMainRoleDetail*msg = dynamic_cast<MsgLoadMainRoleDetail*>(pMsg);
	if (msg)
	{
		ICombatSys* pCombat = m_wpCurEtt->getCombatSys();
		if (pCombat)
		{
			//
			//	initialize prop_modifiers for main role (player itself)
			pCombat->setPropsModifier(prop_vit, msg->prop_vit);
			pCombat->setPropsModifier(prop_str, msg->prop_str);
			pCombat->setPropsModifier(prop_agi, msg->prop_agi);
			pCombat->setPropsModifier(prop_int, msg->prop_int);
			pCombat->setPropsModifier(prop_left, msg->prop_left);
		}
		//
		//	save money for player
		m_wpCurEtt->setProps(Entity::ATTR_RMB, msg->money_g);
		m_wpCurEtt->setProps(Entity::ATTR_MONEY, msg->money_s);

		//
		//	save player current active form type
		m_wpCurPlayer->setActiveForm(msg->activeftype);
	}
}

void PlayerMsgHandler::onLoadRolesResponse(IMsg* pMsg)
{
	MsgLoadRoles*msg = dynamic_cast<MsgLoadRoles*>(pMsg);
	if (msg)
	{
		//
		//	current player entity already in entity manager world , don't need to add
		//	just add all sub roles into current player.
		EntityBuilderAddRoles builder(m_wpCurEtt, *msg);
		builder.build();

		//
		//	notice client 
		//	all role are already loaded, get combat system of player will return
		//	combat system of his main role
		//
		ICombatSys* cs = m_wpCurEtt->getCombatSys();
		if(cs)
		{
			MsgMainRoleAttrResponse* response = new MsgMainRoleAttrResponse;
			response->setSID(pMsg->getSID());

			response->pid = msg->pid;
			response->exp = m_wpCurEtt->getProps(Entity::ATTR_EXP, 0);

			response->hp = cs->getHP();
			response->mp = cs->getMP();
			response->maxhp = cs->getMaxHP();
			response->maxmp = cs->getMaxMP();

			getSvcHost()->postMsg(response);
		}
	}
}

void PlayerMsgHandler::onUpdateRoleResponse(IMsg* pMsg)
{

}

void PlayerMsgHandler::onRemoveRoleResponse(IMsg* pMsg)
{

}